#ifndef __LUOO_MYSQL_RECORDSET_HPP__
#define __LUOO_MYSQL_RECORDSET_HPP__

#include <queue>
#include <vector>
#include <string>

#include <boost/lexical_cast.hpp>

#include "luoo_mysql_header.h"
#include "luoo_mysql_conn_pool.hpp"

namespace luoo
{
	class mysql_record
	{
	public:
		enum trash_type { trash };

	public:
		explicit mysql_record(my_ulonglong column)
			: column_number_(column)
		{}

		template<typename T>
		mysql_record& operator >> (T& value)
		{
			if (!record_.empty())
			{
				value = boost::lexical_cast<T>(record_.front().c_str());
				record_.pop();
			}

			return *this;
		}

		mysql_record& operator >> (trash_type)
		{
			if (!record_.empty())
			{
				record_.pop();
			}

			return *this;
		}

		mysql_record& operator << (MYSQL_ROW row)
		{
			while (!record_.empty())
				record_.pop();

			for (my_ulonglong i = 0; i < column_number_; ++i)
			{
				record_.push(row[i]);
			}

			return *this;
		}

	private:
		my_ulonglong column_number_;
		std::queue<std::string> record_;
	};//class mysql_record
	
	class mysql_database;
	class mysql_record_set 
	{
		friend class mysql_database;
		
	public:
		mysql_record_set()
			: is_successed_(false)
		{}

		mysql_record_set& operator << (MYSQL_RES* result)
		{
			if (!record_set_.empty())
			{
				record_set_.clear();
				mysql_fields_.clear();
			}
			
			if (NULL != result)
			{
				for (my_ulonglong i = 0; i < mysql_num_rows(result); ++i)
				{
					mysql_record record(mysql_num_fields(result));
					record << mysql_fetch_row(result);
					record_set_.push_back(record);
				}

				for (unsigned int i = 0; i < mysql_num_fields(result); ++i)
				{
					MYSQL_FIELD* field = mysql_fetch_field(result);
					mysql_fields_.push_back(*field);
				}
			}

			return *this;
		}

		mysql_record& operator[](int row)
		{
			return record_set_[row];
		}

	public:
		inline unsigned int get_num_fields() { return mysql_fields_.size(); }
		inline unsigned int get_num_rows() { return record_set_.size(); }

		inline std::string& get_sql() { return sql_ ;}
		inline mysql_conn_pool::mysql_ptr get_mysql() { return mysql_; }
		inline bool is_successed() { return is_successed_; }
		inline const char* get_error() { return mysql_error(mysql_); }

	private:
		typedef std::vector<mysql_record> mysql_recordset_type;
		typedef std::vector<st_mysql_field> mysql_fields_type;

	protected:
		std::string sql_;
		bool is_successed_;
		mysql_conn_pool::mysql_ptr mysql_;

	private:
		mysql_fields_type mysql_fields_;
		mysql_recordset_type record_set_;
	};//class mysql_recordset 

}//namespace luoo

#endif//__LUOO_MYSQL_RECORDSET_HPP__